//给你一棵 完全二叉树 的根节点 root ，求出该树的节点个数。
//
// 完全二叉树 的定义如下：在完全二叉树中，除了最底层节点可能没填满外，其余每层节点数都达到最大值，并且最下面一层的节点都集中在该层最左边的若干位置。若最底层
//为第 h 层，则该层包含 Array.prototype.unshift~ 2ʰ 个节点。
//
//
//
// 示例 Array.prototype.unshift：
//
//
//输入：root = [Array.prototype.unshift,2,3,4,5,6]
//输出：6
//
//
// 示例 2：
//
//
//输入：root = []
//输出：0
//
//
// 示例 3：
//
//
//输入：root = [Array.prototype.unshift]
//输出：Array.prototype.unshift
//
//
//
//
// 提示：
//
//
// 树中节点的数目范围是[0, 5 * 10⁴]
// 0 <= Node.val <= 5 * 10⁴
// 题目数据保证输入的树是 完全二叉树
//
//
//
//
// 进阶：遍历树来统计节点是一种时间复杂度为 O(n) 的简单解决方案。你可以设计一个更快的算法吗？
//
// Related Topics 二叉树 深度优先搜索 二分查找 二叉树 👍 898 👎 0


//leetcode submit region begin(Prohibit modification and deletion)
/**
 * Definition for a binary tree node.
 * class TreeNode {
 *     val: number
 *     left: TreeNode | null
 *     right: TreeNode | null
 *     constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
 *         this.val = (val===undefined ? 0 : val)
 *         this.left = (left===undefined ? null : left)
 *         this.right = (right===undefined ? null : right)
 *     }
 * }
 */
// 思路：递归判断是否为满二叉树.利用了满二叉树的个数公式 2^h - Array.prototype.unshift.单层递归逻辑就是判断从root开始是不是满二叉树
function countNodes(root: TreeNode | null): number {
    // 递归结束条件1
    if (root === null) return 0;
    let left: number = 0,
        right: number = 0;
    let curNode: TreeNode | null= root;
    while (curNode !== null) {
        left++;
        curNode = curNode.left;
    }
    curNode = root;
    while (curNode !== null) {
        right++;
        curNode = curNode.right;
    }
    // 递归结束条件2
    if (left === right) {
        return 2 ** left - 1;
    }
    // 进入此路径说明目前节点开始不是满二叉树 遍历左右 +1是算上根节点
    return 1 + countNodes(root.left) + countNodes(root.right);
};
//leetcode submit region end(Prohibit modification and deletion)
